diff options
author | Tim Oram <dev@mitmaro.ca> | 2019-03-16 23:16:37 -0230 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-16 23:16:37 -0230 |
commit | 19dcf3f5e332a02799b75f01214ba5c4cf02b9f2 (patch) | |
tree | 36772b66c304704256044160d0154b8038e4a06b | |
parent | 9ded4718ca3a8ff0aca5f03c813bb10cbe97ba49 (diff) | |
parent | 166a8bc53895a340625c781bb5dbc2f9794a3a23 (diff) |
Merge pull request #95 from MitMaro/rewrite
Core application rewrite
-rw-r--r-- | .editorconfig | 14 | ||||
-rw-r--r-- | Cargo.lock | 136 | ||||
-rw-r--r-- | Cargo.toml | 7 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rwxr-xr-x | scripts/demo.bash | 112 | ||||
-rw-r--r-- | src/action.rs | 47 | ||||
-rw-r--r-- | src/application.rs | 625 | ||||
-rw-r--r-- | src/commit.rs | 220 | ||||
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/constants.rs | 55 | ||||
-rw-r--r-- | src/git_interactive.rs | 169 | ||||
-rw-r--r-- | src/input.rs | 1 | ||||
-rw-r--r-- | src/line.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 62 | ||||
-rw-r--r-- | src/mocks.rs | 59 | ||||
-rw-r--r-- | src/view.rs | 705 | ||||
-rw-r--r-- | src/window.rs | 337 |
17 files changed, 1736 insertions, 836 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ad2c6d8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +insert_final_newline = true + +[*.md] +indent_style = space +indent_size = 4 + +[*.yml] +indent_style = space +indent_size = 4 @@ -11,7 +11,7 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.25" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -32,6 +32,16 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "chrono" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (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" @@ -49,10 +59,11 @@ dependencies = [ name = "git-interactive-rebase-tool" version = "0.7.0" dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pad 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pancurses 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -61,8 +72,8 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -74,21 +85,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.2.43" +version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -98,8 +109,8 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -119,30 +130,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ncurses" -version = "5.97.0" +version = "5.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "pad" -version = "0.1.5" +name = "num-integer" +version = "0.1.39" 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)", + "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 = "pancurses" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ncurses 5.97.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ncurses 5.98.0 (registry+https://github.com/rust-lang/crates.io-index)", "pdcurses-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -152,8 +168,8 @@ name = "pdcurses-sys" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -168,7 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redox_syscall" -version = "0.1.40" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -176,7 +192,15 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -189,8 +213,8 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -203,6 +227,16 @@ dependencies = [ ] [[package]] +name = "time" +version = "0.1.42" +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)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -212,7 +246,15 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.7" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -221,6 +263,14 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "url" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -241,6 +291,11 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "void" +version = "1.0.2" +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" @@ -271,33 +326,40 @@ dependencies = [ "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 bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4916b5addc78ec36cc309acfcdf0b9f9d97ab7b84083118b248709c5b7029356" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum ncurses 5.97.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee821144e7fe6fd1d1c04b8001d92d783ae471a71d60ab506e6c608b83a85ae6" -"checksum pad 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9b8de33465981073e32e1d75bb89ade49062bb853e7c97ec2c13439095563a" -"checksum pancurses 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cedc1409ecbb0a789f39e2a90ae052df6670c1e1c17724587e1872e6ec270e56" +"checksum ncurses 5.98.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ddf9a2b0b4526dc8c5a57c859b0f4415b7b3258c487aaa11e07fbde2877744d" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3058bc37c433096b2ac7afef1c5cdfae49ede0a4ffec3dfc1df1df0959d0ff0" "checksum pdcurses-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90e12bfe55b7080fdfa0742f7a22ce7d5d1da250ca064ae6b81c843a2084fa2a" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"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 smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "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 time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" +"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "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" @@ -1,7 +1,7 @@ [package] name = "git-interactive-rebase-tool" version = "0.7.0" -authors = ["Tim Oram <me@mitmaro.ca>"] +authors = ["Tim Oram <dev@mitmaro.ca>"] license = "ISC" description = "Full feature terminal based sequence editor for git interactive rebase. Written in Rust using ncurses." repository = "https://github.com/MitMaro/git-interactive-rebase-tool" @@ -20,12 +20,13 @@ name = "interactive-rebase-tool" path = "src/main.rs" [dependencies] +chrono = "0.4" clap = "2.32.0" -pad = "0.1.5" +unicode-segmentation = "1.1.0" [dependencies.pancurses] version = "0.16" -features = ["win32"] +features = ["win32", "wide"] [dependencies.git2] version = "0.7.2" @@ -147,10 +147,11 @@ git config --global interactive-rebase-tool.foregroundColor black | ------------------ | ------- | ----- | ----------- | | `autoSelectNext` | false | bool | If true, auto select the next line after action modification | | `foregroundColor` | white | Color | Color used for most text and the UI | -| `indicatorColor` | yellow | Color | Color used for text the indicates or needs to standout | +| `indicatorColor` | cyan | Color | Color used for text the indicates or needs to standout | | `errorColor` | red | Color | Color used for showing error messages | -| `diffAddColor` | green | Color | Color used for lines added in a diff | -| `diffRemoveColor` | red | Color | Color used for lines removed in a diff | +| `diffAddColor` | green | Color | Color used for lines and files added in a diff | +| `diffRemoveColor` | red | Color | Color used for lines and files removed in a diff | +| `diffChangeColor` | yellow | Color | Color used for lines and files changed in a diff | | `pickColor` | green | Color | Color used for the pick action | | `rewordColor` | yellow | Color | Color used for the reword action | | `editColor` | blue | Color | Color used for the edit action | @@ -178,7 +179,7 @@ To start developing the project you will need to [install Rust][install-rust], w You will need `build-essential` and `libncurses5-dev` to build the project. Additionally, you will need `pkg-config` and `liblzma-dev` if you wish to build a release. They can be installed using `apt-get`: - sudo apt-get install build-essential libncurses5-dev + sudo apt-get install build-essential libncursesw5-dev sudo apt-get install pkg-config liblzma-dev diff --git a/scripts/demo.bash b/scripts/demo.bash new file mode 100755 index 0000000..a2b3027 --- /dev/null +++ b/scripts/demo.bash @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +set -x +xdotool windowactivate 6830112 +sleep 0.1 +xdotool type --delay 150 -- 'git rebase -i @~10' +xdotool key "Return" +sleep 1 +xdotool key r +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key e +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key s +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key f +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key d +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key s +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key s +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key s +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key f +sleep 0.3 +xdotool key "Down" +sleep 0.2 +xdotool key r +sleep 0.3 + +xdotool type --delay 300 "jjjkkkk" +sleep 0.3 +xdotool key "Up" +sleep 0.2 +xdotool key "Up" + +sleep 0.3 +xdotool type --delay 300 "pjjjj" + +sleep 0.1 +xdotool key "Up" +sleep 0.1 +xdotool key "Up" +sleep 0.1 +xdotool key "Up" +sleep 0.5 +xdotool key "c" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 1 + +xdotool key "q" +sleep 0.5 +xdotool key 'question' +sleep 0.1 +xdotool key "Down" +sleep 0.1 +xdotool key "Down" +sleep 0.1 +xdotool key "Down" +sleep 0.1 +xdotool key "Down" +sleep 0.1 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 0.2 +xdotool key "Down" +sleep 2 +xdotool key "q" +sleep 0.5 +xdotool key "w" +sleep 2 +xdotool key "y" diff --git a/src/action.rs b/src/action.rs index affdba1..d324525 100644 --- a/src/action.rs +++ b/src/action.rs @@ -36,6 +36,18 @@ impl Action { Action::Squash => "squash", }) } + + pub fn to_abbreviation(&self) -> String { + String::from(match self { + Action::Drop => "d", + Action::Edit => "e", + Action::Exec => "x", + Action::Fixup => "f", + Action::Pick => "p", + Action::Reword => "r", + Action::Squash => "s", + }) + } } #[cfg(test)] @@ -153,4 +165,39 @@ mod tests { fn action_from_str_invalid_action() { assert_eq!(Action::try_from("invalid").unwrap_err(), "Invalid action: invalid"); } + + #[test] + fn action_to_abbreviation_drop() { + assert_eq!(Action::Drop.to_abbreviation(), "d"); + } + + #[test] + fn action_to_abbreviation_edit() { + assert_eq!(Action::Edit.to_abbreviation(), "e"); + } + + #[test] + fn action_to_abbreviation_exec() { + assert_eq!(Action::Exec.to_abbreviation(), "x"); + } + + #[test] + fn action_to_abbreviation_fixup() { + assert_eq!(Action::Fixup.to_abbreviation(), "f"); + } + + #[test] + fn action_to_abbreviation_pick() { + assert_eq!(Action::Pick.to_abbreviation(), "p"); + } + + #[test] + fn action_to_abbreviation_reword() { + assert_eq!(Action::Reword.to_abbreviation(), "r"); + } + + #[test] + fn action_to_abbreviation_squash() { + assert_eq!(Action::Squash.to_abbreviation(), "s"); + } } diff --git a/src/application.rs b/src/application.rs index 9b96ebc..f9c9a53 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,136 +1,319 @@ use action::Action; use git_interactive::GitInteractive; -use window::{ - Window -}; +use window::Window; use input::Input; use config::Config; +use constants::{EXIT_CODE_GOOD, EXIT_CODE_STATE_ERROR, EXIT_CODE_WRITE_ERROR}; +use view::View; +use std::process::ExitStatus; +use std::process::Command; -const EXIT_CODE_GOOD: i32 = 0; -const EXIT_CODE_WRITE_ERROR: i32 = 8; - -#[derive(PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum State { ConfirmAbort, ConfirmRebase, + Exiting, + ExternalEditor, + ExternalEditorFinish, + ExternalEditorError, + Error, Help, List, ShowCommit, + WindowSizeError, } -pub struct Application { - config: Config, - pub exit_code: Option<i32>, +pub struct Application<'a> { + config: &'a Config, + error_message: Option<String>, + exit_code: Option<i32>, git_interactive: GitInteractive, + previous_state: Option<State>, state: State, - window: Window, + view: View<'a>, + window: &'a Window<'a>, } -impl Application { - pub fn new(git_interactive: GitInteractive, window: Window, config: Config) -> Self { +impl <'a> Application <'a> { + pub fn new(git_interactive: GitInteractive, view: View<'a>, window: &'a Window<'a>, config: &'a Config) -> Self { Application { config, + error_message: None, exit_code: None, git_interactive, + previous_state: None, state: State::List, + view, window, } } - - pub fn process_input(&mut self) { + + pub fn run(&mut self) -> Result<Option<i32>, String>{ + self.handle_resize(); + while self.exit_code == None { + // process based on input, allowed to change state + self.process(); + // draw output for state, including state change from process + self.draw(); + // handle input for state + self.handle_input(); + } + self.exit_end()?; + Ok(self.exit_code) + } + + fn get_cursor_index(&self) -> usize { + *self.git_interactive.get_selected_line_index() - 1 + } + + fn process(&mut self) { match self.state { - State::ConfirmAbort => self.process_confirm_abort(), - State::ConfirmRebase => self.process_confirm_rebase(), - State::Help => self.process_help_input(), - State::List => self.process_list_input(), - State::ShowCommit => self.process_show_commit_input(), + State::ConfirmAbort => {}, + State::ConfirmRebase => {}, + State::Error => {}, + State::Exiting => {}, + State::ExternalEditor => self.process_external_editor(), + State::ExternalEditorError => self.process_external_editor_error(), + State::ExternalEditorFinish => self.process_external_editor_finish(), + State::Help => {}, + State::List => self.process_list(), + State::ShowCommit => self.process_show_commit(), + State::WindowSizeError => {}, + } + } + + fn process_external_editor(&mut self) { + if let Err(e) = self.run_editor() { + self.set_error(e, State::ExternalEditorFinish); + return; + } + self.state = State::ExternalEditorFinish; + } + + fn process_external_editor_finish(&mut self) { + if let Err(e) = self.git_interactive.reload_file(self.config.comment_char.as_str()) { + self.set_error(e, State::ExternalEditorError); + return; + } + + if self.git_interactive.get_lines().is_empty() { + self.set_error(String::from("Rebase empty"), State::ExternalEditorError); + // exit will occur in error + return; + } + self.state = State::List; + } + + fn process_external_editor_error(&mut self) { + self.state = State::Exiting; + if self.git_interactive.get_lines().is_empty() { + self.exit_finish(); + return; + } + self.exit_error(); + } + + fn process_list(&mut self) { + let lines = self.git_interactive.get_lines(); + let selected_index = self.get_cursor_index(); + self.view.update_main_top(lines.len(), selected_index); + } + + fn process_show_commit(&mut self) { + if let Err(e) = self.git_interactive.load_commit_stats() { + self.set_error(e, State::List); + }; + } + + fn draw(&self) { + self.window.clear(); + match self.state { + State::ConfirmAbort => self.view.draw_confirm("Are you sure you want to abort"), + State::ConfirmRebase => self.view.draw_confirm("Are you sure you want to rebase"), + State::Error => self.draw_error(), + State::Exiting => self.view.draw_exiting(), + State::ExternalEditor => {}, + State::ExternalEditorError => self.draw_error(), + State::ExternalEditorFinish => {}, + State::Help => self.view.draw_help(), + State::List => self.view.draw_main( + self.git_interactive.get_lines(), + self.get_cursor_index() + ), + State::ShowCommit => self.view.draw_show_commit( + self.git_interactive.get_commit_stats(), + ), + State::WindowSizeError => self.view.draw_window_size_error(), + } + self.window.refresh(); + } + + fn draw_error(&self) { + let message = match self.error_message { + Some(ref msg) => msg.as_str(), + None => "Error...", + }; + self.view.draw_error(message); + } + + fn handle_resize(&mut self) { + let check = self.view.check_window_size(); + if !check && self.state != State::WindowSizeError { + self.previous_state = Some(self.state); + self.state = State::WindowSizeError; + } + else if check && self.state == State::WindowSizeError { + self.state = self.previous_state.unwrap_or(State::List); + self.previous_state = None; + } + } + + fn get_input(&mut self) -> Input { + let input = self.window.get_input(); + if let Input::Resize = input { + self.handle_resize(); } + input + } + + fn get_confirm(&mut self) -> Option<bool> { + let input = self.window.get_confirm(); + if input.is_none() { + self.handle_resize(); + }; + input } - - pub fn draw(&self) { + + fn handle_input(&mut self) { match self.state { - State::ConfirmAbort => { - self.window.draw_confirm("Are you sure you want to abort"); + State::ConfirmAbort => self.handle_confirm_abort_input(), + State::ConfirmRebase => self.handle_confirm_rebase_input(), + State::Error => self.handle_error_input(), + State::Exiting => {}, + State::ExternalEditor => self.handle_external_editor_input(), + State::ExternalEditorError => self.handle_error_input(), + State::ExternalEditorFinish => {}, + State::Help => self.handle_help_input(), + State::List => self.handle_list_input(), + State::ShowCommit => self.handle_show_commit_input(), + State::WindowSizeError => self.handle_window_size_error_input(), + }; + } + + fn handle_help_input(&mut self) { + match self.get_input() { + Input::MoveCursorDown => { + self.view.update_help_top(false, false); + }, + Input::MoveCursorUp => { + self.view.update_help_top(true, false); + }, + Input::Resize => { + self.view.update_help_top(true, true); }, - State::ConfirmRebase => { - self.window.draw_confirm("Are you sure you want to rebase"); + _ => { + self.state = State::List; } - State::Help => { - self.window.draw_help(); + } + } + + fn handle_show_commit_input(&mut self) { + match self.get_input() { + Input::MoveCursorDown => { + self.view.update_commit_top( + false, + false, + self.git_interactive.get_commit_stats_length() + ); }, - State::List => { - self.window.draw( - self.git_interactive.get_lines(), - *self.git_interactive.get_selected_line_index() + Input::MoveCursorUp => { + self.view.update_commit_top( + true, + false, + self.git_interactive.get_commit_stats_length() ); }, - State::ShowCommit => { - self.window.draw_show_commit( - self.git_interactive.get_selected_line_hash(), - self.git_interactive.get_git_root() + Input::Resize => { + self.view.update_commit_top( + true, + false, + self.git_interactive.get_commit_stats_length() ); }, + _ => { + self.state = State::List; + } } } - fn abort(&mut self) { - self.git_interactive.clear(); - self.finish(); - } - - fn finish(&mut |