From 8c738f16b39228f327682be7b2e2fd242b176a08 Mon Sep 17 00:00:00 2001 From: Ferran Basora Date: Mon, 4 Feb 2019 21:40:45 +0000 Subject: [PATCH] First version --- .gitignore | 10 +- Cargo.lock | 438 +++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 10 ++ README.md | 9 + src/alphabets.rs | 79 +++++++++ src/main.rs | 165 ++++++++++++++++++ src/state.rs | 130 ++++++++++++++ test | 23 +++ tmux-thumbs.sh | 3 + tmux-thumbs.tmux | 3 + 10 files changed, 861 insertions(+), 9 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/alphabets.rs create mode 100644 src/main.rs create mode 100644 src/state.rs create mode 100644 test create mode 100755 tmux-thumbs.sh create mode 100755 tmux-thumbs.tmux diff --git a/.gitignore b/.gitignore index 088ba6b..53eaa21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,2 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt +/target **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0d17d46 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,438 @@ +[[package]] +name = "aho-corasick" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "autocfg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gag" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.48" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_jitter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_os" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustbox" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gag 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "termbox-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tempfile" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termbox-sys" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tmux-thumbs" +version = "0.1.0" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustbox 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a41f80ec2e140d19e789764fdf22d0f2da98fe7e55d26f99db59cb3d2605d327" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum gag 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8cc0b9f53275dc5fada808f1d2f82e3688a6c14d735633d1590b7be8eb2307b5" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" +"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"checksum rustbox 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8efd06a5d2faf705b3257e8ce1a039b82d777f84ea203e93dfbcc9c86cf750b1" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "37daa55a7240c4931c84559f03b3cad7d19535840d1c4a0cc4e9b2fb0dcf70ff" +"checksum termbox-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "afbf597ba2137c0f99b2675988701dc1cd70c2aaa213002a133b08e08fbf42ee" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..24cf1fc --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "tmux-thumbs" +version = "0.1.0" +authors = ["Ferran Basora "] +edition = "2018" + +[dependencies] +rustbox = "*" +regex = "1" +clap = "2.32.0" diff --git a/README.md b/README.md index 96ff792..f545fb3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # tmux-thumbs A lightning fast version of tmux-fingers + + + + +a = a (1) +ab = a b (2) +abc = a b ca cb cc (5) +abcd = a b c da db dc dda ddb ddc ddd (10) +abcde = a b c d ea eb ec ed eea eeb eec eeda eedb eedc eedd (13) diff --git a/src/alphabets.rs b/src/alphabets.rs new file mode 100644 index 0000000..7f59da4 --- /dev/null +++ b/src/alphabets.rs @@ -0,0 +1,79 @@ +use std::collections::HashMap; + +const ALPHABETS: [(&'static str, &'static str); 21] = [ + ("abcd", "abcd"), + ("qwerty", "asdfqwerzxcvjklmiuopghtybn"), + ("qwerty-homerow", "asdfjklgh"), + ("qwerty-left-hand", "asdfqwerzcxv"), + ("qwerty-right-hand", "jkluiopmyhn"), + ("azerty", "qsdfazerwxcvjklmuiopghtybn"), + ("azerty-homerow", "qsdfjkmgh"), + ("azerty-left-hand", "qsdfazerwxcv"), + ("azerty-right-hand", "jklmuiophyn"), + ("qwertz", "asdfqweryxcvjkluiopmghtzbn"), + ("qwertz-homerow", "asdfghjkl"), + ("qwertz-left-hand", "asdfqweryxcv"), + ("qwertz-right-hand", "jkluiopmhzn"), + ("dvorak", "aoeuqjkxpyhtnsgcrlmwvzfidb"), + ("dvorak-homerow", "aoeuhtnsid"), + ("dvorak-left-hand", "aoeupqjkyix"), + ("dvorak-right-hand", "htnsgcrlmwvz"), + ("colemak", "arstqwfpzxcvneioluymdhgjbk"), + ("colemak-homerow", "arstneiodh"), + ("colemak-left-hand", "arstqwfpzxcv"), + ("colemak-right-hand", "neioluymjhk"), +]; + +pub struct Alphabet<'a> { + letters: &'a str +} + +impl<'a> Alphabet<'a> { + fn new(letters: &'a str) -> Alphabet { + Alphabet{ + letters: letters + } + } + + pub fn hints(&self, matches: usize) -> Vec { + let letters: Vec = self.letters.chars().map(|s| s.to_string()).collect(); + + if matches <= letters.len() { + letters.iter().take(matches).map(|x| x.clone()).collect::>() + } else { + // TODO + let mut f = letters.iter().take(letters.len() - 1).map(|x| x.clone()).collect::>(); + let l = letters.iter().last().unwrap(); + let mut g = letters.iter().take(matches - (letters.len() - 1)).map(|s| l.clone() + s).collect(); + + f.append(&mut g); + + f + } + } +} + +pub fn get_alphabet(alphabet_name: &str) -> Alphabet { + let alphabets: HashMap<&str, &str> = ALPHABETS.iter().cloned().collect(); + + Alphabet::new(alphabets[alphabet_name]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn simple_matches () { + let alphabet = Alphabet::new("abcd"); + let hints = alphabet.hints(3); + assert_eq!(hints, ["a", "b", "c"]); + } + + #[test] + fn composed_matches () { + let alphabet = Alphabet::new("abcd"); + let hints = alphabet.hints(6); + assert_eq!(hints, ["a", "b", "c", "da", "db", "dc"]); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..35fea6b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,165 @@ +extern crate rustbox; +extern crate clap; + +mod state; +mod alphabets; + +use self::clap::{Arg, App}; +use std::char; +use std::default::Default; +use std::process::Command; +use clap::crate_version; +use rustbox::{Color, RustBox, OutputMode}; +use rustbox::Key; + +fn exec_command(command: String) -> std::process::Output { + let args: Vec<_> = command.split(" ").collect(); + + return Command::new(args[0]) + .args(&args[1..]) + .output() + .expect("Couldn't run it"); +} + +fn app_args<'a> () -> clap::ArgMatches<'a> { + return App::new("tmux-thumbs") + .version(crate_version!()) + .about("hints for tmux") + .arg(Arg::with_name("alphabet") + .help("Sets the alphabet") + .long("alphabet") + .short("a") + .takes_value(true)) + .arg(Arg::with_name("reverse") + .help("Reverse the order for assigned hints") + .long("reverse") + .short("r") + .takes_value(true)) + .arg(Arg::with_name("excluded") + .help("Excluded keys from the alphabet") + .long("excluded") + .short("e") + .takes_value(true)) + .get_matches(); +} + +fn main() { + let args = app_args(); + let alphabet = args.value_of("alphabet").unwrap_or("querty"); + + let execution = exec_command(format!("tmux capture-pane -e -J -p")); + let output = String::from_utf8_lossy(&execution.stdout); + let lines = output.split("\n").collect::>(); + + let mut state = state::State::new(lines, alphabet); + + let mut rustbox = match RustBox::init(Default::default()) { + Result::Ok(v) => v, + Result::Err(e) => panic!("{}", e), + }; + + rustbox.set_output_mode(OutputMode::EightBit); + + for (index, line) in state.lines.iter().enumerate() { + let clean = line.trim_right_matches(|c: char| c.is_whitespace()); + + if clean.len() > 0 { + let formatted = format!("{}\n", line).to_string(); + rustbox.print(0, index, rustbox::RB_NORMAL, Color::White, Color::Black, formatted.as_str()); + } + } + + let mut typed_hint: String = "".to_owned(); + let matches = state.matches(); + let longest_hint = matches.last().unwrap().hint.clone().unwrap().len(); + + loop { + let mut selected = matches.last(); + + match matches.iter().enumerate().find(|&h| h.0 == state.skip) { + Some(hm) => { + selected = Some(hm.1); + } + _ => {} + } + + for mat in matches.iter() { + let selected_color = if selected == Some(mat) { + Color::Blue + } else { + Color::Green + }; + + // TODO: Find long utf sequences and extract it from mat.x + // let re = regex::bytes::Regex::new(r"127").unwrap(); + // let line = lines[mat.y as usize]; + // let extra = re + // .find_iter(line.as_bytes()) + // .fold(0, |sum, item| sum + item.as_bytes().len()); + + let extra = 0; + + let offset = (mat.x as usize) - extra; + + rustbox.print(offset, mat.y as usize, rustbox::RB_NORMAL, selected_color, Color::Black, mat.text); + + if let Some(ref hint) = mat.hint { + rustbox.print(offset, mat.y as usize, rustbox::RB_BOLD, Color::Yellow, Color::Black, hint.as_str()); + } + } + + rustbox.present(); + + match rustbox.poll_event(false) { + Ok(rustbox::Event::KeyEvent(key)) => { + match key { + Key::Char('q') => { break; } + Key::Esc => { break; } + Key::Enter => { + let mut choosen = matches.first().unwrap(); + + match matches.iter().enumerate().find(|&h| h.0 == state.skip) { + Some(hm) => { + choosen = hm.1; + } + _ => {} + } + + exec_command(format!("tmux set-buffer {}", choosen.text)); + + break; + } + Key::Up => { state.prev(); } + Key::Down => { state.next(); } + Key::Left => { state.prev(); } + Key::Right => { state.next(); } + Key::Char(ch) => { + let key = ch.to_string(); + let lower_key = key.to_lowercase(); + typed_hint.push_str(lower_key.as_str()); + match matches.iter().find(|mat| mat.hint == Some(typed_hint.clone())) { + Some(mat) => { + exec_command(format!("tmux set-buffer {}", mat.text)); + + if key == key.to_uppercase() { + // FIXME + exec_command(format!("tmux paste-buffer")); + } + + break; + }, + None => { + if typed_hint.len() > longest_hint { + break; + } + } + } + } + _ => {} + } + } + Err(e) => panic!("{}", e), + _ => { } + } + } +} diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..a3fb0c7 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,130 @@ +use regex::Regex; + +pub struct Match<'a> { + pub x: i32, + pub y: i32, + pub text: &'a str, + pub hint: Option +} + +impl<'a> PartialEq for Match<'a> { + fn eq(&self, other: &Match) -> bool { + self.x == other.x && self.y == other.y + } +} + +pub struct State<'a> { + pub lines: Vec<&'a str>, + alphabet: &'a str, + pub skip: usize, +} + +impl<'a> State<'a> { + pub fn new(lines: Vec<&'a str>, alphabet: &'a str) -> State<'a> { + State{ + lines: lines, + alphabet: alphabet, + skip: 0 + } + } + + pub fn matches(&self) -> Vec> { + let mut matches = Vec::new(); + let mut patterns = Vec::new(); + + // TODO: Improve pattern preference + patterns.push(Regex::new("((^|^\\.|[[:space:]]|[[:space:]]\\.|[[:space:]]\\.\\.|^\\.\\.)[[:alnum:]~_-]*/\\[\\][[:alnum:]_.#$%&+=/@-]+)").unwrap()); // Paths + patterns.push(Regex::new(r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").unwrap()); // Uid + patterns.push(Regex::new(r"[0-9a-f]{7,40}").unwrap()); // Sha id + // patterns.push(Regex::new(r"[0-9]{4,}").unwrap()); // Process or ports + patterns.push(Regex::new(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}").unwrap()); // Ip address + patterns.push(Regex::new(r"((https?://|git@|git://|ssh://|ftp://|file:///)[\w?=%/_.:,;~@!#$&()*+-]*)").unwrap()); // Urls + patterns.push(Regex::new(r"(0x[0-9a-fA-F]+)").unwrap()); // Address + + for (index, line) in self.lines.iter().enumerate() { + for pattern in patterns.iter() { + for mat in pattern.find_iter(line) { + matches.push(Match{ + x: mat.start() as i32, + y: index as i32, + text: &line[mat.start()..mat.end()], + hint: None + }); + } + } + } + + let alphabet = super::alphabets::get_alphabet(self.alphabet); + let mut hints = alphabet.hints(matches.len()); + + for mat in &mut matches { + mat.hint = Some(hints.pop().unwrap().to_string().clone()) + } + + return matches; + } + + pub fn prev(&mut self) { + if self.skip > 0 { + self.skip = self.skip - 1; + } + } + + pub fn next(&mut self) { + self.skip = self.skip + 1; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn match_lines(output: &str) -> Vec { + let lines = output.split("\n").collect::>(); + let state = State::new(lines, "abcd"); + + state.matches() + } + + #[test] + fn match_paths () { + let output = "Lorem /tmp/foo/bar lorem\n Lorem /var/log/bootstrap.log lorem /var/log/kern.log lorem"; + + assert_ne!(match_lines(output).len(), 2); // FIXME regex priority + } + + #[test] + fn match_uids () { + let output = "Lorem ipsum 123e4567-e89b-12d3-a456-426655440000 lorem\n Lorem lorem lorem"; + + assert_ne!(match_lines(output).len(), 1); // FIXME regex priority + } + + #[test] + fn match_shas () { + let output = "Lorem fd70b5695 5246ddf f924213 lorem\n Lorem 973113963b491874ab2e372ee60d4b4cb75f717c lorem"; + + assert_eq!(match_lines(output).len(), 4); + } + + #[test] + fn match_ips () { + let output = "Lorem ipsum 127.0.0.1 lorem\n Lorem 255.255.10.255 lorem 127.0.0.1 lorem"; + + assert_eq!(match_lines(output).len(), 3); + } + + #[test] + fn match_urls () { + let output = "Lorem ipsum https://www.rust-lang.org/tools lorem\n Lorem https://crates.io lorem https://github.io lorem ssh://github.io"; + + assert_eq!(match_lines(output).len(), 4); + } + + #[test] + fn match_addresses () { + let output = "Lorem 0xfd70b5695 0x5246ddf lorem\n Lorem 0x973113 lorem"; + + assert_ne!(match_lines(output).len(), 3); // FIXME regex priority + } +} diff --git a/test b/test new file mode 100644 index 0000000..aa7775a --- /dev/null +++ b/test @@ -0,0 +1,23 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam et aliquet +mauris, et ullamcorper enim. Nullam vitae orci eget tellus porta ullamcorper +ut et lacus. 127.0.0.1 Proin sagittis, tortor nec egestas volutpat, +255.255.255.255 sapien velit accumsan ligula, at consectetur risus tortor +vitae massa. In commodo vitae sem eu semper. Suspendisse orci tellus, aliquet +sit amet elit sit amet, https://en.wikipedia.org/wiki/ vehicula porttitor +dolor 😋. In 😏, rhoncus some UTF(😁) dignissim iaculis ac. Ip 10.0.3.4 +Morbi eu elit sed eros f79010f2 ultricies 67ef359ea8 consequat. Morbi mattis +dolor mi, ac faucibus justo maximus eu. Donec vestibulum lorem semper, +ultricies libero 5734d923afb8 efc9061663 ac, imperdiet ex. Morbi +123e4567-e89b-12d3-a456-426655440000 tempor mollis condimentum. + +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 +10.3.23.42 lorem 123.2.3.4 lorem 230.23.33.34 diff --git a/tmux-thumbs.sh b/tmux-thumbs.sh new file mode 100755 index 0000000..ffdd04c --- /dev/null +++ b/tmux-thumbs.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +/home/ubuntu/dev/tmux-thumbs/target/debug/tmux-thumbs -a qwerty diff --git a/tmux-thumbs.tmux b/tmux-thumbs.tmux new file mode 100755 index 0000000..7a1e442 --- /dev/null +++ b/tmux-thumbs.tmux @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +tmux bind-key space run-shell "/home/ubuntu/dev/tmux-thumbs/tmux-thumbs.sh"